package com.jwsoft.manager.core.integration.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.PhoneUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bifang.assistant.common.enums.ExcelTypeEnum;
import com.bifang.engine.assistant.core.annotation.ApiService;
import com.bifang.engine.assistant.core.annotation.OpApi;
import com.bifang.engine.assistant.core.annotation.SaveOplog;
import com.bifang.engine.assistant.core.enums.AuTypeEnum;
import com.bifang.engine.assistant.core.enums.AuthStatusEnum;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.bifang.engine.assistant.core.enums.FuncTypeEnum;
import com.bifang.engine.assistant.core.exception.AppException;
import com.bifang.engine.assistant.core.utils.SessionUtil;
import com.bifang.engine.cache.redis.RedisHelper;
import com.bifang.module.base.common.vo.dict.DictQueryVO;
import com.bifang.module.base.common.vo.dict.SelectVO;
import com.bifang.module.base.common.vo.excel.*;
import com.bifang.module.base.core.helper.ExcelCommonHelper;
import com.bifang.module.base.core.integration.DictIntegration;
import com.bifang.module.base.core.integration.ExcelIntegration;
import com.bifang.module.system.common.enums.CardTypeEnum;
import com.bifang.module.system.core.dao.model.ExcelModel;
import com.bifang.module.system.core.dao.model.ExcelParam;
import com.bifang.module.system.core.dao.service.ExcelModelService;
import com.bifang.module.system.core.dao.service.ExcelParamService;
import com.bifang.module.system.core.dao.service.SysDictService;
import com.bifang.module.system.core.dao.service.SysUserService;
import com.jwsoft.manager.common.enums.EnrollStatusFormalEnum;
import com.jwsoft.manager.common.enums.SchoolCategoryEnum;
import com.jwsoft.manager.common.vo.eduSchool.EduSchoolVO;
import com.jwsoft.manager.common.vo.eduSchoolVacancy.EduSchoolVacancyQueryVO;
import com.jwsoft.manager.common.vo.eduStudentEnroll.EduStudentEnrollExcelSaveVO;
import com.jwsoft.manager.common.vo.eduStudentEnroll.EduStudentEnrollVO;
import com.jwsoft.manager.common.vo.eduStudentEnroll.StudentEnrollFileVO;
import com.jwsoft.manager.common.vo.eduSyncJhApply.EduSyncJhApplyVO;
import com.jwsoft.manager.common.vo.eduSyncJhApprove.EduSyncJhApproveVO;
import com.jwsoft.manager.common.vo.eduSyncJhDelete.EduSyncExistInfo;
import com.jwsoft.manager.common.vo.eduSyncJhDelete.EduSyncJhDeleteQueryVO;
import com.jwsoft.manager.common.vo.eduSyncJhEnroll.EduSyncJhEnrollVO;
import com.jwsoft.manager.core.dao.model.*;
import com.jwsoft.manager.core.dao.service.*;
import com.jwsoft.manager.core.integration.EduPolicyStudentImportIntegration;
import com.jwsoft.manager.core.integration.EduSyncJhApplyIntegration;
import com.jwsoft.manager.core.integration.EduSyncJhApproveIntegration;
import com.jwsoft.manager.core.integration.EduSyncJhEnrollIntegration;
import com.jwsoft.manager.core.util.EduHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * @author zjl
 * @version 1.0
 * @date 2024/7/5 0005 10:59
 */
@ApiService(funcCode = "eduPolicyStudentImport", title = "政策学生导入")
public class EduPolicyStudentImportImpl implements EduPolicyStudentImportIntegration {
    @Autowired
    public ExcelIntegration excelIntegration;
    @Autowired
    public DictIntegration dictIntegration;
    @Autowired
    public EduSchoolService eduSchoolService;
    @Autowired
    public ExcelCommonHelper excelCommonHelper;
    @Autowired
    public EduHelper eduHelper;
    @Autowired
    public ExcelModelService excelModelService;
    @Autowired
    public ExcelParamService excelParamService;
    @Autowired
    public SysDictService sysDictService;
    @Autowired
    public EduFormSpecialService eduFormSpecialService;
    @Autowired
    public EduStudentEnrollPreService eduStudentEnrollPreService;
    @Autowired
    public EduStudentEnrollService eduStudentEnrollService;
    @Autowired
    public RedisHelper redisHelper;
    @Autowired
    public EduSchoolConfigService eduSchoolConfigService;
    @Autowired
    public SysUserService sysUserService;
    @Autowired
    public EduSyncJhEnrollIntegration enrollIntegration;
    @Autowired
    public EduSyncJhApproveIntegration approveIntegration;
    @Autowired
    public EduSyncJhApplyIntegration applyIntegration;
    @Autowired
    private EduSyncJhDeleteService eduSyncJhDeleteService;

    @Override
    @OpApi(funcCode = "eduPolicyStudentImport0001", title = "政策学生导入表模板下载（PC）", funcType = FuncTypeEnum.other, checkPrivilege = BoolEnum.FALSE)
    public void downloadModel(ExcelVO vo, HttpServletResponse response) {
        Map<String, List<SelectVO>> dictMap = new HashMap<>();
        dictMap.put("configType", getConfigTypeDictMap());
        dictMap.put("sex", getSexDictMap());
        dictMap.put("cardType",getCardTypeDictMap());
        dictMap.put("FatherCardType",getFatherCardTypeDictMap());
        String areaCode = SessionUtil.getAreaCode();
        if (areaCode.equalsIgnoreCase("330700")){
            dictMap.put("schoolName", getSchoolDictMap(null));
        }else{
            dictMap.put("schoolName", getSchoolDictMap(areaCode));
        }
        vo.setDictMap(dictMap);
        excelIntegration.downloadModel(vo, response);
    }

    @Override
    @OpApi(funcCode = "eduPolicyStudentImport0002", title = "政策学生导入表excel导入保存（PC）", funcType = FuncTypeEnum.insert)
    public ExcelReadVO readExcel(ExcelVO vo, MultipartFile file) {
        //判断是否在经办业务期内
        ExcelReadVO excelReadVO = new ExcelReadVO();
        excelReadVO.setCount(0);
        ExcelModelVO excelModelVO = this.getModel(vo);
        InputStream in = null;
        Integer year = eduHelper.thisYear();
        try {
            in = file.getInputStream();
            List<Map<String, Object>> list = excelCommonHelper.readExcel(excelModelVO, in, true);
            List<Map<String, Object>> successList = new ArrayList<>();
            List<Map<String, Object>> errorList = new ArrayList<>();
            for (Map<String, Object> map : list) {
                EduStudentEnrollVO eduStudentEnrollVO = JSON.parseObject(JSON.toJSONString(map), EduStudentEnrollVO.class);
                QueryWrapper<EduSchool> schoolQueryWrapper = new QueryWrapper<>();
                schoolQueryWrapper.lambda().ne(EduSchool::getSchoolCategory, SchoolCategoryEnum.KINDERGARTEN.getType());
                List<EduSchool> schoolList = eduSchoolService.list(schoolQueryWrapper);
                String remarks = "";
                boolean flag = false;
                if (ObjectUtils.isEmpty(eduStudentEnrollVO.getFullName())){
                    remarks += "学生姓名不能为空！";
                    flag = true;
                }
                if (ObjectUtils.isEmpty(eduStudentEnrollVO.getIdcard())|| ObjectUtils.isEmpty(eduStudentEnrollVO.getFatherName().trim())){
                    remarks += "学生身份证不能为空！";
                    flag = true;
                }
                if (StringUtils.isNotBlank(eduStudentEnrollVO.getIdcard())){
                    List<String> enrollStatusList = new ArrayList<>();
                    enrollStatusList.add(EnrollStatusFormalEnum.dsh.getType());
                    enrollStatusList.add(EnrollStatusFormalEnum.dlq.getType());
                    enrollStatusList.add(EnrollStatusFormalEnum.lq.getType());
                    enrollStatusList.add(EnrollStatusFormalEnum.hy.getType());
                    enrollStatusList.add(EnrollStatusFormalEnum.fs.getType());
                    enrollStatusList.add(EnrollStatusFormalEnum.bh.getType());
                    QueryWrapper<EduStudentEnroll> enrollQueryWrapper = new QueryWrapper<>();
                    enrollQueryWrapper.lambda().select(EduStudentEnroll::getIdcard).eq(EduStudentEnroll::getIdcard, eduStudentEnrollVO.getIdcard())
                            .eq(EduStudentEnroll::getYear, year)
                            .in(EduStudentEnroll::getEnrollStatus, enrollStatusList);
                    if (eduStudentEnrollService.count(enrollQueryWrapper) > 0) {
                        remarks += "该学生已存在报名信息！";
                        flag = true;
                    }
                }
                if (StringUtils.isBlank(eduStudentEnrollVO.getCardType())){
                    remarks += "学生身份证类型不能为空！";
                    flag = true;
                }else{
                    DictQueryVO dictQueryVO = new DictQueryVO();
                    dictQueryVO.setDictField("CARDTYPE");
                    dictQueryVO.setDictValue(eduStudentEnrollVO.getCardType().trim());
                    String key = dictIntegration.getKey(dictQueryVO);
                    if (StringUtils.isBlank(key)) {
                        remarks += "学生身份证类型格式不对！";
                        flag = true;
                    }
                    eduStudentEnrollVO.setCardTypeName(eduStudentEnrollVO.getCardType().trim());
                    eduStudentEnrollVO.setCardType(key);
                }
                if (CardTypeEnum.idcard.getType().equals(eduStudentEnrollVO.getCardType()) && !IdcardUtil.isValidCard(eduStudentEnrollVO.getIdcard())) {
                    remarks += "学生身份证有误！";
                    flag = true;
                }
                if (ObjectUtils.isEmpty(eduStudentEnrollVO.getBirthYmd())){
                    remarks += "出生日期不能为空！";
                    flag = true;
                }
                if (ObjectUtils.isEmpty(eduStudentEnrollVO.getSex())){
                    remarks += "性别不能为空！";
                    flag = true;
                }else{
                    DictQueryVO dictQueryVO = new DictQueryVO();
                    dictQueryVO.setDictField("SEX");
                    dictQueryVO.setDictValue(eduStudentEnrollVO.getSex().trim());
                    String key = dictIntegration.getKey(dictQueryVO);
                    if (StringUtils.isBlank(key)) {
                        remarks += "性别数据格式不对！";
                        flag = true;
                    }
                    eduStudentEnrollVO.setSexName(eduStudentEnrollVO.getSex().trim());
                    eduStudentEnrollVO.setSex(key);
                }
                if (ObjectUtils.isEmpty(eduStudentEnrollVO.getHouseholdPlace())){
                    remarks += "户籍地不能为空！";
                    flag = true;
                }
                if (ObjectUtils.isEmpty(eduStudentEnrollVO.getAddress())){
                    remarks += "居住地不能为空！";
                    flag = true;
                }
                if (ObjectUtils.isEmpty(eduStudentEnrollVO.getFatherIdcard())){
                    remarks += "监护人身份证不能为空！";
                    flag = true;
                }
                if (ObjectUtils.isEmpty(eduStudentEnrollVO.getFatherCellphone())){
                    remarks += "监护人联系方式不能为空！";
                    flag = true;
                }
                if (ObjectUtils.isEmpty(eduStudentEnrollVO.getEnrollNum())){
                    remarks += "报名批次不能为空！";
                    flag = true;
                }
                if (StringUtils.isBlank(eduStudentEnrollVO.getFatherIdcard())){
                    remarks += "监护人证件类型不能为空！";
                    flag = true;
                } else{
                    DictQueryVO dictQueryVO = new DictQueryVO();
                    dictQueryVO.setDictField("CARDTYPE");
                    dictQueryVO.setDictValue(eduStudentEnrollVO.getFatherCardType().trim());
                    String key = dictIntegration.getKey(dictQueryVO);
                    if (StringUtils.isBlank(key)) {
                        remarks += "监护人身份证类型格式不对！";
                        flag = true;
                    }
                    eduStudentEnrollVO.setFatherCardTypeName(eduStudentEnrollVO.getFatherCardType().trim());
                    eduStudentEnrollVO.setFatherCardType(key);
                }
                if (CardTypeEnum.idcard.getType().equals(eduStudentEnrollVO.getFatherCardType()) && !IdcardUtil.isValidCard(eduStudentEnrollVO.getFatherIdcard())) {
                    remarks += "监护人身份证有误！";
                    flag = true;
                }
                if (ObjectUtils.isEmpty(eduStudentEnrollVO.getFatherName()) || ObjectUtils.isEmpty(eduStudentEnrollVO.getFatherName().trim())) {
                    remarks += "监护人姓名不能为空！";
                    flag = true;
                } else {
                    eduStudentEnrollVO.setFatherName(
                            Validator.isChinese(eduStudentEnrollVO.getFatherName())
                                    ? eduStudentEnrollVO.getFatherName().replaceAll(" ", "").replaceAll(" ", "").trim()
                                    : eduStudentEnrollVO.getFatherName().trim());
                }
                if (!ObjectUtils.isEmpty(eduStudentEnrollVO.getFatherCellphone()) && !PhoneUtil.isMobile(eduStudentEnrollVO.getFatherCellphone())) {
                    remarks += "请输入正确的手机号码！";
                    flag = true;
                }

                AtomicBoolean schoolFlag = new AtomicBoolean(false);
                schoolList.forEach(
                        school -> {
                            if (!ObjectUtils.isEmpty(eduStudentEnrollVO.getSchoolName())
                                    && school.getShortName()
                                    .replaceAll("（", "(")
                                    .replaceAll("）", ")")
                                    .equals(
                                            eduStudentEnrollVO.getSchoolName()
                                                    .replaceAll("（", "(")
                                                    .replaceAll("）", ")"))) {
                                schoolFlag.set(true);
                                eduStudentEnrollVO.setSchoolId(school.getOrgId());
                                eduStudentEnrollVO.setShortName(school.getSchoolName());
                                eduStudentEnrollVO.setSchoolNature(school.getSchoolNature());
                                eduStudentEnrollVO.setSchoolCategory(school.getSchoolCategory());
                                eduStudentEnrollVO.setAreaCode(school.getAreaCode());
                            }
                            if (ObjectUtils.isEmpty(eduStudentEnrollVO.getSchoolId())){
                                if (!ObjectUtils.isEmpty(eduStudentEnrollVO.getSchoolName())
                                        && school.getSchoolName()
                                        .replaceAll("（", "(")
                                        .replaceAll("）", ")")
                                        .equals(
                                                eduStudentEnrollVO.getSchoolName()
                                                        .replaceAll("（", "(")
                                                        .replaceAll("）", ")"))) {
                                    schoolFlag.set(true);
                                    eduStudentEnrollVO.setSchoolId(school.getOrgId());
                                    eduStudentEnrollVO.setShortName(school.getSchoolName());
                                    eduStudentEnrollVO.setSchoolNature(school.getSchoolNature());
                                    eduStudentEnrollVO.setSchoolCategory(school.getSchoolCategory());
                                    eduStudentEnrollVO.setAreaCode(school.getAreaCode());
                                }
                            }
                        });
                if (!schoolFlag.get()) {
                    remarks += "找不到招生学校!";
                    flag = true;
                }
                if (StringUtils.isBlank(eduStudentEnrollVO.getConfigName())) {
                    remarks += "招生类别不能为空!";
                    flag = true;
                }else {
                    LambdaQueryWrapper<EduFormSpecial> queryWrapper = new QueryWrapper<EduFormSpecial>().lambda()
                            .eq(EduFormSpecial::getYear, eduHelper.thisYear())
                            .eq(EduFormSpecial::getAreaCode, eduStudentEnrollVO.getAreaCode());
                    List<EduFormSpecial> formSpecials = eduFormSpecialService.list(queryWrapper);
                    List<EduFormSpecial> collect = formSpecials.stream().filter(formSpecial -> formSpecial.getBigClassValue().equals(eduStudentEnrollVO.getConfigName())).collect(Collectors.toList());
                    if (collect.size() == 0){
                        remarks += "招生类别不存在!";
                        flag = true;
                    }
                }
                if (flag) {
                    eduStudentEnrollVO.setExcelRemarks(remarks);
                    errorList.add(JSON.parseObject(JSON.toJSONString(eduStudentEnrollVO), Map.class));
                } else {
                    successList.add(JSON.parseObject(JSON.toJSONString(eduStudentEnrollVO), Map.class));
                }
            }
            excelReadVO.setCount(successList.size() + errorList.size());
            excelReadVO.setSuccessCount(successList.size());
            excelReadVO.setSuccessList(successList);
            excelReadVO.setErrorList(errorList);
            excelReadVO.setErrorCount(errorList.size());
        } catch (AppException appEx) {
            throw appEx;
        } catch (IOException e) {
            throw new AppException("读取文件异常:" + e.getMessage());
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return excelReadVO;
    }

    @Override
    @OpApi(funcCode = "eduPolicyStudentImport0003", title = "政策生excel导入保存（PC）", funcType = FuncTypeEnum.insert)
    @SaveOplog(
            operationType = "eduPolicyStudentImport0003",
            operationName = "政策生excel导入保存（PC）",
            dataType = "batch",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public void addExcel(EduStudentEnrollExcelSaveVO vo) {
        if (CollectionUtils.isEmpty(vo.getEduStudentEnrollVOList())) {
            throw new AppException("没有传入需要保存的信息");
        }
        Integer year = eduHelper.thisYear();
        List<String> enrollStatusList = new ArrayList<>();
        enrollStatusList.add(EnrollStatusFormalEnum.dsh.getType());
        enrollStatusList.add(EnrollStatusFormalEnum.dlq.getType());
        enrollStatusList.add(EnrollStatusFormalEnum.lq.getType());
        enrollStatusList.add(EnrollStatusFormalEnum.hy.getType());
        enrollStatusList.add(EnrollStatusFormalEnum.fs.getType());
        enrollStatusList.add(EnrollStatusFormalEnum.bh.getType());
        for (EduStudentEnrollVO eduStudentEnrollVO : vo.getEduStudentEnrollVOList()){
            LambdaQueryWrapper<EduSchoolConfig> configLambdaQueryWrapper = new QueryWrapper<EduSchoolConfig>()
                    .lambda().select(EduSchoolConfig::getEnrolment).eq(EduSchoolConfig::getSchoolId, eduStudentEnrollVO.getSchoolId())
                    .eq(EduSchoolConfig::getYear, year);
            EduSchoolConfig eduSchoolConfig = eduSchoolConfigService.getOne(configLambdaQueryWrapper, false);
            LambdaQueryWrapper<EduStudentEnroll> lambdaQueryWrapper = new QueryWrapper<EduStudentEnroll>().lambda().eq(EduStudentEnroll::getSchoolId, eduStudentEnrollVO.getSchoolId())
                    .eq(EduStudentEnroll::getYear, year)
                    .in(EduStudentEnroll::getEnrollStatus, enrollStatusList);
            long enrollCount = eduStudentEnrollService.count(lambdaQueryWrapper);
            if(enrollCount>=eduSchoolConfig.getEnrolment()){
                throw new AppException(eduStudentEnrollVO.getSchoolName()+"报名人数已超过计划人数不能导入");
            }
            LambdaQueryWrapper<EduStudentEnrollPre> queryWrapper = new QueryWrapper<EduStudentEnrollPre>().lambda()
                    .eq(EduStudentEnrollPre::getIdcard, eduStudentEnrollVO.getIdcard())
                    .eq(EduStudentEnrollPre::getYear, eduHelper.thisYear());
            EduStudentEnrollPre eduStudentEnrollPre = eduStudentEnrollPreService.getOne(queryWrapper, false);
            if (!ObjectUtils.isEmpty(eduStudentEnrollPre)){
                if (StringUtils.isNotBlank(eduStudentEnrollPre.getFatherIdcard())){
                    eduStudentEnrollVO.setFatherIdcard(eduStudentEnrollPre.getFatherIdcard());
                    eduStudentEnrollVO.setFatherName(eduStudentEnrollPre.getFatherName());
                    eduStudentEnrollVO.setFatherCardType(eduStudentEnrollPre.getFatherCardType());
                    if (StringUtils.isBlank(eduStudentEnrollPre.getFatherCellphone())){
                        eduStudentEnrollVO.setFatherCellphone(eduStudentEnrollVO.getFatherCellphone());
                    }
                }
                if (StringUtils.isNotBlank(eduStudentEnrollPre.getMotherIdcard())){
                    eduStudentEnrollVO.setMotherIdcard(eduStudentEnrollPre.getMotherIdcard());
                    eduStudentEnrollVO.setMotherName(eduStudentEnrollPre.getMotherName());
                    eduStudentEnrollVO.setMotherCardType(eduStudentEnrollPre.getMotherCardType());
                    if(StringUtils.isBlank(eduStudentEnrollPre.getMotherCellphone())){
                        eduStudentEnrollVO.setMotherCellphone(eduStudentEnrollVO.getFatherCellphone());
                    }
                }
            }
            EduSchoolVO eduSchool = eduSchoolService.getDetail(eduStudentEnrollVO.getSchoolId());
            eduStudentEnrollVO.setYear(year);
            eduStudentEnrollVO.setApplyId(this.getApplyId(eduStudentEnrollVO.getYear(), eduSchool.getSchoolNature(), eduSchool.getSchoolNum(), 97, eduSchool.getOrgId(), 1));
            eduStudentEnrollVO.setEnrollStatus(EnrollStatusFormalEnum.lq.getType());
            eduStudentEnrollVO.setAuthStatus(AuthStatusEnum.YES.getType());
            eduStudentEnrollVO.setAuthTime(new Date());
            eduStudentEnrollVO.setAuthRemarks("政策生导入审核通过");
            eduStudentEnrollVO.setAuthUserId(SessionUtil.getUserId());
            eduStudentEnrollVO.setAdmitFlag("1");
            eduStudentEnrollVO.setAdmitTime(new Date());
            eduStudentEnrollVO.setAdmitRemarks("教育局管理员政策生导入直接录取");
            eduStudentEnrollVO.setAdmitUserId(SessionUtil.getUserId());
            eduStudentEnrollVO.setIcertificatioFlag("0");
            eduStudentEnrollVO.setAborigineFlag("0");
            eduStudentEnrollVO.setServiceFlag("0");
            eduStudentEnrollVO.setSource("6");
            eduStudentEnrollVO.setPrivateAppointFlag(BoolEnum.FALSE.getType());
            eduStudentEnrollVO.setSpecialFlag(BoolEnum.TRUE.getType());
            eduStudentEnrollVO.setAreaCode(eduSchool.getAreaCode());
            eduStudentEnrollVO.setConfigNameAlias(eduStudentEnrollVO.getConfigName());
            List<SelectVO> dictField = sysDictService.getDictByDictField("SCHOOLNATURE");
            Map<String, String> dict = dictField.stream().collect(Collectors.toMap(
                    SelectVO::getDictKey, SelectVO::getDictValue, (k1, k2) -> k1));
            eduStudentEnrollVO.setConfigTypeName(dict.get(eduSchool.getSchoolNature()));
            LambdaQueryWrapper<EduFormSpecial> specialLambdaQueryWrapper = new QueryWrapper<EduFormSpecial>().lambda()
                    .eq(EduFormSpecial::getYear, year)
                    .eq(EduFormSpecial::getAreaCode, eduSchool.getAreaCode())
                    .eq(EduFormSpecial::getBigClassValue, eduStudentEnrollVO.getConfigName());
            EduFormSpecial formSpecial = eduFormSpecialService.getOne(specialLambdaQueryWrapper, false);
            if (!ObjectUtils.isEmpty(formSpecial)){
                eduStudentEnrollVO.setFormId(formSpecial.getFormSpecialId());
            }
            EduStudentEnroll eduStudentEnroll = Convert.convert(EduStudentEnroll.class, eduStudentEnrollVO);
            // 金华全市录取查询
            //需要调用查询接口，判断其他区县是否有录取数据
            EduSyncJhDeleteQueryVO queryVO = new EduSyncJhDeleteQueryVO();
            queryVO.setIdcard(eduStudentEnroll.getIdcard());
            queryVO.setName(eduStudentEnroll.getFullName());
            queryVO.setApplyCountyCode(eduStudentEnroll.getAreaCode());
            EduSyncExistInfo eduSyncExistInfo = eduSyncJhDeleteService.querySyncInfo(queryVO);
            if (eduSyncExistInfo != null && "3".equals(eduSyncExistInfo.getType())) {
                //如果返回结果不为空并且是录取状态 判断行政区划是否为当前区县;
                if (!eduStudentEnroll.getAreaCode().equals(eduSyncExistInfo.getApplyCountyCode())) {
                    //如果不是当前区县，不能进行处理
                    throw new AppException("该学生以被" + eduSyncExistInfo.getApplyCountyName() + "教育局录取！");
                }
            }

            List<String> enrollStatus = new ArrayList<>();
            enrollStatus.add(EnrollStatusFormalEnum.dlq.getType());
            enrollStatus.add(EnrollStatusFormalEnum.lq.getType());
            QueryWrapper<EduStudentEnroll> query = new QueryWrapper<>();
            query.lambda().select(EduStudentEnroll::getStudentEnrollId)
                    .eq(EduStudentEnroll::getParentId, eduStudentEnroll.getStudentEnrollId())
                    .in(EduStudentEnroll::getEnrollStatus, enrollStatus)
                    .ne(EduStudentEnroll::getSchoolId, eduStudentEnroll.getSchoolId());
            if (eduStudentEnrollService.count(query) > 0) {
                throw new AppException(eduStudentEnroll.getFullName() + "，金华市区内其他学校待录取或者已录取");
            }
            eduStudentEnroll.setEnrollStatus(EnrollStatusFormalEnum.lq.getType());
            //同步报名表，审核表，录取表
            // 1.同步报名数据
            EduSyncJhApplyVO applyVO = new EduSyncJhApplyVO();
            applyVO.setYear(eduStudentEnroll.getYear());
            applyVO.setSchoolCategory(eduStudentEnroll.getSchoolCategory());
            applyVO.setCardType(eduStudentEnroll.getCardType());
            applyVO.setName(eduStudentEnroll.getFullName());
            applyVO.setIdcard(eduStudentEnroll.getIdcard());
            applyVO.setSex(eduStudentEnroll.getSex());
            applyVO.setHouseholdAddress(eduStudentEnroll.getHouseholdPlace());
            applyVO.setResidentialAddress(eduStudentEnroll.getAddress());
            if (StringUtils.isNotBlank(eduStudentEnroll.getFatherIdcard())) {
                applyVO.setMasterGuardianNumber(eduStudentEnroll.getFatherIdcard());
                applyVO.setMasterGuardianName(eduStudentEnroll.getFatherName());
                applyVO.setMasterGuardianRelation("1");
            }
            if (StringUtils.isNotBlank(eduStudentEnroll.getMotherIdcard())) {
                applyVO.setSlaveGuardianNumber(eduStudentEnroll.getMotherIdcard());
                applyVO.setSlaveGuardianName(eduStudentEnroll.getMotherName());
                applyVO.setSlaveGuardianRelation("2");
            }
            applyVO.setApplyCountyCode(eduStudentEnroll.getAreaCode());
            //当前时间戳
            applyVO.setApplyTime(System.currentTimeMillis());
            if (!applyVO.getCardType().equals(com.jwsoft.manager.common.enums.CardTypeEnum.idcard)) {
                if (applyVO.getSex().equals("1")) {
                    applyVO.setSex("0");
                } else if (applyVO.getSex().equals("2")) {
                    applyVO.setSex("1");
                }
            }
            try {
                applyIntegration.saveSyncApplyInfo2(applyVO);
            } catch (AppException e) {
                throw new AppException(e.getMessage());
            } catch (Exception e) {
                throw new AppException(e.getMessage());
            }

            //2.同步审核表数据
            EduSyncJhApproveVO syncJhApproveVO = new EduSyncJhApproveVO();
            syncJhApproveVO.setSchoolCategory(eduStudentEnroll.getSchoolCategory());
            syncJhApproveVO.setApproveState(AuthStatusEnum.YES.getType());
            syncJhApproveVO.setApproveTime(new Date());
            syncJhApproveVO.setApproveHuman(SessionUtil.getUserId());
            syncJhApproveVO.setCardType(eduStudentEnroll.getCardType());
            syncJhApproveVO.setName(eduStudentEnroll.getFullName());
            syncJhApproveVO.setIdcard(eduStudentEnroll.getIdcard());
            syncJhApproveVO.setApplyCountyCode(eduStudentEnroll.getAreaCode());
            syncJhApproveVO.setApproveOpinion(eduStudentEnroll.getAuthRemarks());
            try {
                approveIntegration.saveSyncApproveInfo2(syncJhApproveVO);
            } catch (AppException e) {
                throw new AppException(e.getMessage());
            } catch (Exception e) {
                throw new AppException(e.getMessage());
            }

            //3.同步录取表数据
            EduSyncJhEnrollVO syncJhEnrollVO = new EduSyncJhEnrollVO();
            syncJhEnrollVO.setSchoolCategory(eduStudentEnroll.getSchoolCategory());
            syncJhEnrollVO.setCardType(eduStudentEnroll.getCardType());
            syncJhEnrollVO.setName(eduStudentEnroll.getFullName());
            syncJhEnrollVO.setIdcard(eduStudentEnroll.getIdcard());
            syncJhEnrollVO.setEnrollState(AuthStatusEnum.YES.getType());
            syncJhEnrollVO.setEnrollHuman(SessionUtil.getUserId());
            syncJhEnrollVO.setEnrollTime(new Date());
            syncJhEnrollVO.setEnrollSchoolName(eduStudentEnroll.getSchoolName());
            syncJhEnrollVO.setEnrollSchoolCode(eduStudentEnroll.getSchoolId());
            syncJhEnrollVO.setApplyCountyCode(eduStudentEnroll.getAreaCode());
            syncJhEnrollVO.setEnrollOpinion(eduStudentEnroll.getAuthRemarks());
            enrollIntegration.saveSyncEnrollInfo2(syncJhEnrollVO);
            //保存
            eduStudentEnrollService.save(eduStudentEnroll);

        }
    }

    @Override
    @OpApi(funcCode = "eduPolicyStudentImport0003", title = "政策生错误数据下载", funcType = FuncTypeEnum.other, checkPrivilege = BoolEnum.TRUE)
    public void downloadErrorExcel(StudentEnrollFileVO vo, HttpServletResponse response) {
        ExcelVO excelVO = new ExcelVO();
        excelVO.setModelCode(vo.getModelCode());
        Map<String, List<SelectVO>> dictMap = new HashMap<>();
        dictMap.put("configType", getConfigTypeDictMap());
        dictMap.put("sex", getSexDictMap());
        dictMap.put("cardType",getCardTypeDictMap());
        dictMap.put("FatherCardType",getFatherCardTypeDictMap());
        String areaCode = SessionUtil.getAreaCode();
        if (areaCode.equalsIgnoreCase("330700")){
            dictMap.put("schoolName", getSchoolDictMap(null));
        }else{
            dictMap.put("schoolName", getSchoolDictMap(areaCode));
        }
        excelVO.setDictMap(dictMap);
        ExcelModelVO excelModelVO = getModel(excelVO);
        String fileName = vo.getFileName();
        if (StringUtils.isBlank(fileName)) {
            fileName =
                    excelModelVO.getModelName()
                            + "_"
                            + DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_PATTERN)
                            + "."
                            + (StringUtils.isBlank(excelModelVO.getExcelType())
                            ? "xls"
                            : excelModelVO.getExcelType());
        }
        EduSchoolVacancyQueryVO queryVO = new EduSchoolVacancyQueryVO();
        List<EduStudentEnrollVO> errorList1 = vo.getErrorList();
        List<Object> errorList = Convert.toList(Object.class, errorList1);
        excelCommonHelper.downloadExcelBean(excelModelVO, errorList, fileName, response);
    }

    public ExcelModelVO getModel(ExcelVO vo) {
        return this.getModel(vo.getModelCode(), vo.getExcelVersion(), vo.getDictMap());
    }
    public ExcelModelVO getModel(
            String modelCode, String version, Map<String, List<SelectVO>> dictMap) {
        if (StringUtils.isBlank(modelCode)) {
            throw new AppException("模板编号不能为空");
        }
        QueryWrapper<ExcelModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ExcelModel::getModelCode, modelCode);
        if (StringUtils.isBlank(version)) {
            queryWrapper.lambda().eq(ExcelModel::getNewFlag, BoolEnum.TRUE.getType());
        } else {
            queryWrapper.lambda().eq(ExcelModel::getExcelVersion, version);
        }
        ExcelModel excelModel = excelModelService.getOne(queryWrapper, false);
        if (excelModel == null) {
            throw new AppException("未找到excel模板信息");
        }
        ExcelModelVO excelModelVO = Convert.convert(ExcelModelVO.class, excelModel);
        // 获取字段信息
        List<ExcelParamVO> paramVOList = this.getByModelId(excelModelVO.getId());
        for (ExcelParamVO excelParamVO : paramVOList) {
            if (excelParamVO.getHeaderBgColor() == null) {
                excelParamVO.setHeaderBgColor(excelModelVO.getHeaderBgColor());
            }
            if (excelParamVO.getHeaderColor() == null) {
                excelParamVO.setHeaderColor(excelModelVO.getHeaderColor());
            }
            if (excelParamVO.getBodyBgColor() == null) {
                excelParamVO.setBodyBgColor(excelModelVO.getBodyBgColor());
            }
            if (excelParamVO.getBodyColor() == null) {
                excelParamVO.setBodyColor(excelModelVO.getBodyColor());
            }
            if (StringUtils.isBlank(excelParamVO.getWrapText())) {
                excelParamVO.setWrapText(excelModelVO.getWrapText());
            }
            if (StringUtils.isBlank(excelParamVO.getFontName())) {
                excelParamVO.setFontName(excelModelVO.getFontName());
            }
            if (excelParamVO.getFontSize() == null) {
                excelParamVO.setFontSize(excelModelVO.getFontSize());
            }
            if (excelParamVO.getBorderSize() == null) {
                excelParamVO.setBorderSize(excelModelVO.getBorderSize());
            }
            if (excelParamVO.getBorderColor() == null) {
                excelParamVO.setBorderColor(excelModelVO.getBorderColor());
            }
            if (ExcelFieldVO.CellTypeEnum.SELECT.getType().equals(excelParamVO.getCellType())
                    || ExcelFieldVO.CellTypeEnum.MULTIPLESELECT
                    .getType()
                    .equals(excelParamVO.getCellType())) {
                String dictField = excelParamVO.getDictField();
                if (StringUtils.isBlank(dictField)) {
                    dictField = excelParamVO.getKey();
                }
                if (dictMap != null && dictMap.containsKey(dictField)) {
                    excelParamVO.setCodeList(dictMap.get(dictField));
                } else {
                    List<SelectVO> selectList = sysDictService.getDictByDictField(dictField);
                    excelParamVO.setCodeList(selectList);
                }
            }
        }
        excelModelVO.setParamVOList(paramVOList);
        if (StringUtils.isBlank(excelModelVO.getExcelType())) {
            excelModelVO.setExcelType(ExcelTypeEnum.xls.toString());
        }
        if (StringUtils.isBlank(excelModelVO.getExcelMode())) {
            excelModelVO.setExcelMode("2");
        }
        return excelModelVO;
    }
    public List<ExcelParamVO> getByModelId(String excelModelId) {
        QueryWrapper<ExcelParam> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .eq(ExcelParam::getExcelModelId, excelModelId)
                .orderByAsc(ExcelParam::getOrderNo)
                .orderByAsc(ExcelParam::getCreateTime);
        List<ExcelParam> list = excelParamService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        List<ExcelParamVO> voList = Convert.toList(ExcelParamVO.class, list);
        return voList;
    }
    private List<SelectVO> getSchoolDictMap(String areaCode) {
        HashMap<String, Object> map = new HashMap<>();
        LambdaQueryWrapper<EduSchool> queryWrapper = new QueryWrapper<EduSchool>()
                .lambda().eq(EduSchool::getRecruitStatus, "0")
                .eq(StringUtils.isNotBlank(areaCode),EduSchool::getAreaCode, areaCode)
                .ne(EduSchool::getSchoolCategory, SchoolCategoryEnum.KINDERGARTEN.getType());
        List<EduSchool> schoolList = eduSchoolService.list(queryWrapper);
        List<SelectVO> schoolDictList = new ArrayList<>();
        schoolList.forEach(
                item -> {
                    SelectVO selectVO = new SelectVO();
                    selectVO.setDictKey(item.getOrgId());
                    selectVO.setDictValue(item.getShortName());
                    selectVO.setDictField("schoolName");
                    selectVO.setFieldName("学校");
                    schoolDictList.add(selectVO);
                });
        return schoolDictList;
    }
    private List<SelectVO> getConfigTypeDictMap() {
        LambdaQueryWrapper<EduFormSpecial> queryWrapper = new QueryWrapper<EduFormSpecial>().lambda().groupBy(EduFormSpecial::getBigClassValue);
        List<EduFormSpecial> formSpecialList = eduFormSpecialService.list(queryWrapper);
        List<SelectVO> configTypeDictList = new ArrayList<>();
        formSpecialList.forEach(item -> {
            SelectVO selectVO = new SelectVO();
            selectVO.setDictKey(item.getBigClassKey().toString());
            selectVO.setDictValue(item.getBigClassValue());
            selectVO.setDictField("configType");
            selectVO.setFieldName("招生类别");
            configTypeDictList.add(selectVO);
        });
        return configTypeDictList;
    }
    private List<SelectVO> getCardTypeDictMap() {
        DictQueryVO queryVO = new DictQueryVO();
        queryVO.setDictFields("CARDTYPE");
        Map<String, List<SelectVO>> dictBatch = dictIntegration.getDictBatch(queryVO);
        List<SelectVO> cardTypeList = dictBatch.get("CARDTYPE");
        List<SelectVO> cardTypeDictList = new ArrayList<>();
        cardTypeList.forEach(item -> {
            SelectVO selectVO = new SelectVO();
            selectVO.setDictKey(item.getDictKey());
            selectVO.setDictValue(item.getDictValue());
            selectVO.setDictField("cardType");
            selectVO.setFieldName("证件类型");
            cardTypeDictList.add(selectVO);
        });
        return cardTypeDictList;
    }
    private List<SelectVO> getFatherCardTypeDictMap() {
        DictQueryVO queryVO = new DictQueryVO();
        queryVO.setDictFields("CARATYPE");
        Map<String, List<SelectVO>> dictBatch = dictIntegration.getDictBatch(queryVO);
        List<SelectVO> cardTypeList = dictBatch.get("CARATYPE");
        List<SelectVO> cardTypeDictList = new ArrayList<>();
        cardTypeList.forEach(item -> {
            SelectVO selectVO = new SelectVO();
            selectVO.setDictKey(item.getDictKey());
            selectVO.setDictValue(item.getDictValue());
            selectVO.setDictField("fatherCardType");
            selectVO.setFieldName("证件类型");
            cardTypeDictList.add(selectVO);
        });
        return cardTypeDictList;
    }
    private List<SelectVO> getSexDictMap() {
        DictQueryVO queryVO = new DictQueryVO();
        queryVO.setDictFields("SEX");
        Map<String, List<SelectVO>> dictBatch = dictIntegration.getDictBatch(queryVO);
        List<SelectVO> sex = dictBatch.get("SEX");
        List<SelectVO> sexDictList = new ArrayList<>();
        sex.forEach(item -> {
            SelectVO selectVO = new SelectVO();
            selectVO.setDictKey(item.getDictKey());
            selectVO.setDictValue(item.getDictValue());
            selectVO.setDictField("sex");
            selectVO.setFieldName("性别");
            sexDictList.add(selectVO);
        });
        return sexDictList;
    }
    public  String getApplyId(Integer year,String schoolNature,String schoolNum,Integer orderNo,String shcoolId,Integer count){
        if(count==null){
            count=count+1;
        }
        if(count>10){
            //超过10次未能比对到不重复的数据，返回报错
            throw new AppException("系统繁忙，请重新点提交");
        }
        String y=year % 100+"";
        String num = StringUtils.leftPad(schoolNum, 9, "0");
        String orderNoId = StringUtils.leftPad(orderNo + "", 2, "0");
        String applyId=y+num+orderNoId;
        if("0".equals(schoolNature)){
            String redisKey="ywEnroll:gb:"+shcoolId+":"+orderNo;
            if(redisHelper.hasKey(redisKey)) {
                String redisApplyId= (String) redisHelper.get(redisKey);
                applyId=String.valueOf(Long.parseLong(redisApplyId)+1);
                redisHelper.set(redisKey,applyId,259200);
            }else{
                //公办
                String max=eduStudentEnrollService.queryMaxApplyId(applyId,shcoolId,year);
                if(StringUtils.isBlank(max)){
                    applyId=applyId+StringUtils.leftPad("1", 4, "0");
                }else{
                    applyId=String.valueOf(Long.parseLong(max)+1);
                }
                redisHelper.set(redisKey,applyId,259200);
            }
            return applyId;
        }else{
            //民办或者公参民转公
            String redisKey="ywEnroll:mb:"+shcoolId+":"+orderNo;
            Integer randomId =null;
            if(redisHelper.hasKey(redisKey)) {

                List<Integer> randomList= (List<Integer>) redisHelper.get(redisKey);
                if(CollectionUtils.isEmpty(randomList)){
                    Integer[] randomNums= NumberUtil.generateBySet(1,9999,3000);
                    randomList= Arrays.stream(randomNums).distinct().collect(Collectors.toList());
                    randomId=randomList.get(0);
                    randomList.remove(randomId);
                    redisHelper.set(redisKey,randomList,259200);
                }else{
                    randomId=randomList.get(0);
                    randomList.remove(randomId);
                    redisHelper.set(redisKey,randomList,259200);
                }
            }else{
                Integer[] randomNums=NumberUtil.generateBySet(1,9999,3000);
                List<Integer> randomList=Arrays.stream(randomNums).distinct().collect(Collectors.toList());
                randomId=randomList.get(0);
                randomList.remove(randomId);
                redisHelper.set(redisKey,randomList,259200);
            }

            applyId=applyId+StringUtils.leftPad(randomId + "", 4, "0");

        }
        QueryWrapper<EduStudentEnroll> queryWrapper=new QueryWrapper<>();
        queryWrapper.lambda().select(EduStudentEnroll::getStudentEnrollId).eq(EduStudentEnroll::getSchoolId,shcoolId)
                .eq(EduStudentEnroll::getYear,year)
                .eq(EduStudentEnroll::getApplyId,applyId);
        if(eduStudentEnrollService.count(queryWrapper)>0){
            applyId=this.getApplyId(year,schoolNature,schoolNum,orderNo,shcoolId,count);
        }
        return applyId;
    }
}
